
#include <string.h>
#include <stdint.h>
#include <arm_compat.h>

#include "Timer.h"
#include "BSP_Timer.h"

#define MAX_CALL_NUM	32

Timer_T* timerList[MAX_CALL_NUM];

/*
注册一个定时器回调函数
*/
void Timer_Register(Timer_T* timer){
	uint32_t i;
	
	for(i = 0; i < MAX_CALL_NUM; ++i){
		if(!timerList[i]){
			timerList[i] = timer;
			break;
		}
	}
}

/*
注销一个定时器回调函数
*/
void Timer_Unregister(Timer_T* timer){
	uint32_t i;
	
	for(i = 0; i < MAX_CALL_NUM; ++i){
		if(timerList[i] == timer){
			timerList[i] = 0;
		}
	}
}

/*
定时器滴答函数，每次硬件定时器中断时调用
*/

static void Timer_DoTick(Timer_T* timer){
	if(timer->tick){
		timer->tick--;
		if(timer->tick == 0){
			if(timer->control & 0x04){
				//异步调用
				timer->control |= 0x80;
			}
			else{
				timer->cb();
			}
			if(timer->control & 0x02){
				timer->tick = timer->period;
			}
		}
	}
}

void Timer_Tick(void){
	uint32_t i;
	for(i = 0; i < MAX_CALL_NUM; ++i){
		if(timerList[i] && (timerList[i]->control & 0x01)){
			Timer_DoTick(timerList[i]);
		}
	}
}

void Timer_Config(Timer_T* timer, uint16_t period, uint8_t cycle, uint8_t asyn, void(*cb)(void)){
	timer->control = 0;
	if(cycle){
		timer->control |= 0x02;
	}
	if(asyn){
		timer->control |= 0x04;
	}
	timer->period = period;
	timer->cb = cb;
}

void Timer_Setup(Timer_T* timer, uint16_t period, uint8_t cycle, uint8_t asyn, void(*cb)(void)){
	Timer_Config(timer, period, cycle, asyn, cb);
	Timer_Register(timer);
}

void Timer_Start(Timer_T* timer){
	if(timer->tick == 0){
		timer->tick = timer->period;
	}
	timer->control |= 0x01;
}

void Timer_Stop(Timer_T* timer){
	timer->control &= ~ 0x01;
}

void Timer_Restart(Timer_T* timer){
	timer->tick = timer->period;
	timer->control |= 0x01;
}

void Timer_Reset(Timer_T* timer, uint16_t period){
	timer->period = period;
	Timer_Restart(timer);
}

void Timer_Service(void){
	uint32_t i;
	for(i = 0; i < MAX_CALL_NUM; ++i){
		if(timerList[i]){			
			__disable_irq();
			if(timerList[i]->control & 0x80){
				timerList[i]->control &= ~ 0x80;
				__enable_irq();
				timerList[i]->cb();
			}
			else{
				__enable_irq();
			}
		}
	}
}

int Timer_IsActive(Timer_T* timer){
	return (timer->control & 0x01) != 0;
}

/*
初始化定时器回调列表
*/
void Timer_Init(void){
	memset(timerList, 0, sizeof(timerList));
}


